package top.goldenyear.porpoise.system.permission.service;

import cn.hutool.v7.core.collection.CollUtil;
import cn.hutool.v7.core.text.StrUtil;
import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.easy.query.solon.annotation.Db;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import top.goldenyear.porpoise.common.core.exception.ErrorCode;
import top.goldenyear.porpoise.common.core.exception.ServiceException;
import top.goldenyear.porpoise.common.core.util.tree.TreeUtils;
import top.goldenyear.porpoise.framework.web.core.service.BaseService;
import top.goldenyear.porpoise.system.permission.dto.RolePermissionDto;
import top.goldenyear.porpoise.system.permission.model.*;
import top.goldenyear.porpoise.system.permission.model.base.BaseRolePermission;
import top.goldenyear.porpoise.system.permission.model.proxy.RolePermissionProxy;

/**
 * 角色权限表 Service 服务层
 *
 * @author airhead
 * @since 2024-10-12
 */
@Component
@Slf4j
public class RolePermissionService extends BaseService<RolePermission, RolePermissionProxy> {
  @Db private EasyEntityQuery easyEntityQuery;
  @Inject private RoleService roleService;
  @Inject private PermissionService permissionService;

  public RolePermissionService() {
    super(RolePermission.class, RolePermissionProxy.class);
  }

  public Boolean updateRolePermission(RolePermissionDto rolePermissionDto) {
    Integer roleId = rolePermissionDto.getRoleId();
    if (roleId == null) {
      throw new ServiceException(ErrorCode.builder().msg("角色 id 不能为空").build());
    }

    delete(rolePermissionProxy -> rolePermissionProxy.roleId().eq(roleId));
    if (CollUtil.isEmpty(rolePermissionDto.getPermissionIdList())) {
      return true;
    }

    List<RolePermission> list = new ArrayList<>();
    Set<Integer> permissionIdSet = new HashSet<>(rolePermissionDto.getPermissionIdList());
    for (Integer permissionId : permissionIdSet) {
      RolePermission rolePermission = new RolePermission();
      rolePermission.setRoleId(roleId);
      rolePermission.setPermissionId(permissionId);
      list.add(rolePermission);
    }

    return batchSave(list);
  }

  public RolePermissionDto listRolePermission(Integer roleId) {
    Role role = roleService.getById(roleId);
    if (role == null) {
      throw new ServiceException(ErrorCode.builder().msg("角色 id 不存在").build());
    }

    List<RolePermission> permissionList =
        list(rolePermissionProxy -> rolePermissionProxy.roleId().eq(roleId));
    List<Integer> permissionIds =
        permissionList.stream().map(BaseRolePermission::getPermissionId).toList();

    RolePermissionDto rolePermissionDto = new RolePermissionDto();
    rolePermissionDto.setRoleId(role.getId());
    rolePermissionDto.setRoleName(role.getName());
    rolePermissionDto.setRoleCode(role.getCode());
    rolePermissionDto.setPermissionIdList(permissionIds);
    return rolePermissionDto;
  }

  public RouteTree treeRoute() {
    List<Permission> permissionList =
        permissionService.list(
            permissionProxy -> {
              permissionProxy.status().eq(1);
              List<Integer> typeList = new ArrayList<>();
              typeList.add(1);
              typeList.add(2);
              permissionProxy.type().in(typeList);
            });
    List<RouteNode> list = new ArrayList<>();
    for (Permission permission : permissionList) {
      RouteNode routeNode = RouteNode.convert(permission);
      list.add(routeNode);
    }
    List<RouteNode> routes = TreeUtils.buildTree(list);
    RouteTree routeTree = new RouteTree();
    routeTree.setRoutes(routes);
    return routeTree;
  }

  public Boolean isRouteExist(String routeName) {
    if (StrUtil.isBlank(routeName)) {
      return false;
    }

    Permission permission =
        permissionService.get(
            permissionProxy -> {
              permissionProxy.routeName().eq(routeName);
            });

    return permission != null;
  }

  @Override
  protected EasyEntityQuery easyEntityQuery() {
    return easyEntityQuery;
  }
}
